import React, { Fragment, useEffect, useState } from 'react';
import { Select, Spin } from 'antd';
import PropTypes from 'prop-types';

import _ from 'lodash';

import './main.less';

const Option = Select.Option;

/**
 * 可远程搜索的Select组件
 */
const SearchSelect = (props) => {
    const [lastFetchId,setLastFetchId] = useState(0);
    const [searchVal,setSearchVal] = useState("");
    const [data,setData] = useState([]);
    const [currentPage,setCurrentPage] = useState(1);
    const [hasNext,setHasNext] = useState(false);
    const [isLoadingFirstPage,setIsLoadingFirstPage] = useState(false);
    const [isLoadingMore,setIsLoadingMore] = useState(false);
    const [value,setValue] = useState(props.value)

    useEffect(()=>{
        fetch(searchVal);
    },[]);

    const debounceFetch = (v,p) => _.debounce(fetch(v,p), 300);
    /** 远程搜索函数 */
   const fetch = async (searchVal, pageNo = 1) => {
        try {
            setLastFetchId(lastFetchId++)
            const fetchId = lastFetchId;
            const loadedData = data;
            setSearchVal(searchVal);
            setIsLoadingFirstPage(pageNo === 1)
            setIsLoadingMore(pageNo > 1 )
            const { code, result } = await props.fetch?.(searchVal, pageNo);
            if (fetchId !== lastFetchId) {
                return;
            }
            if (code === 0) {
                const { result: data, pageNo: currentPage, hasNext } = result;
                setData(pageNo === 1 ? data : [...loadedData, ...data])
                setCurrentPage(currentPage)
                setHasNext(hasNext);
            }
        } catch (error) {
            console.log(error);
        } finally {
            setIsLoadingFirstPage(false);
            setIsLoadingMore(false);
        }
    };
    /** 值改变处理函数 */
   const handleChange = (value) => {
    setValue(value)
    setSearchVal('')
    setCurrentPage(1)
    setHasNext(false)
     fetch(searchVal);
        props.onChange?.(value);
    };

    /** 下拉菜单滚动回调 */
    const onPopupScroll = (e) => {
        const { scrollTop, clientHeight, scrollHeight } = e.target;

        if (scrollTop + clientHeight + 1 >= scrollHeight && hasNext) {
            debounceFetch(searchVal, currentPage + 1); // 加载下一页数据
        }
    };

        // const { value, data, isLoadingFirstPage, isLoadingMore } = this.state;

        const { keyAttr, labelAttr, style, placeholder, allowClear } = props;

        const dropdownRender = (menu) => {
            return isLoadingFirstPage ? (
                <div className="first-page-loading">
                    <Spin size="small" />
                </div>
            ) : (
                <Fragment>
                    {menu}
                    {isLoadingMore ? (
                        <div className="more-page-loading">
                            <Spin size="small" />
                        </div>
                    ) : null}
                </Fragment>
            );
        };

        return (
            <Select
                value={value}
                style={{ width: '200px', ...style }}
                placeholder={placeholder}
                allowClear={allowClear ?? true}
                dropdownRender={dropdownRender}
                dropdownMatchSelectWidth={false}
                defaultActiveFirstOption={false}
                showArrow={false}
                filterOption={false}
                showSearch={true}
                onChange={handleChange}
                onSearch={debounceFetch}
                onPopupScroll={onPopupScroll}
            >
                {data.map((item) => (
                    <Option key={item[keyAttr]}>{item[labelAttr]}</Option>
                ))}
            </Select>
        );
    }


export default SearchSelect;
